import java.util.ArrayList;


public class Grammar {

	private ArrayList<String> VN;
	private ArrayList<String> VT;
	private Productions P;
	private String S;
	
	public Grammar(){
		
		this.VN= new ArrayList<String>();
		this.VT= new ArrayList<String>();
		this.P= new Productions();
		this.S= "";
		
	}
	
	public Grammar(String VN, String VT, String P, String S, String delimiter){
		
		if(delimiter.equals(null)) delimiter= ";";
		
		this.setP(VN, delimiter);
		this.setP(VT, delimiter);
		this.setP(P, delimiter);
		this.setS(S);
	}
	
	public Grammar(ArrayList<String> vn, ArrayList<String> vt, Productions p, String s){
		
		this.setP(p);
		this.setS(s);
		this.setVN(vn);
		this.setVT(vt);
	}
	
	public Grammar(String grammar, String S){
		
		this.setS(S);
		this.P= new Productions();
		
		this.createGrammar(grammar);
		
	}
	
	public void createGrammar(String grammar){
		
		String[] prod= Utility.StringSplitByDelimiter(grammar, ";");
		String tmpKey, tmpProduction;
		int index=0;
		String vn= "", vt= "";
		
		for(String tmp : prod){
			
			//System.out.println("production= "+tmp);
			
			index= tmp.indexOf("->");
			tmpKey= tmp.substring(0, index);
			
			if(Character.isUpperCase(tmpKey.charAt(0)) && !vn.contains(tmpKey)) vn+= tmpKey+";";
			else if(Character.isLowerCase(tmpKey.charAt(0)) && !vt.contains(tmpKey)) vt+= tmpKey+";";
				
			tmpProduction= tmp.substring(index+2);
			char[] a_char= tmpProduction.toCharArray();			
			
			for(char c : a_char){

				if(c!= '|'){
					if(Character.isUpperCase(c) && !vn.contains(Character.toString(c))) vn+= Character.toString(c)+";";
					else if(Character.isLowerCase(c) && !vt.contains(Character.toString(c))) vt+= Character.toString(c)+";";
				}
			}
			
			this.P.addProduction(tmpKey, tmpProduction);
			this.setVN(vn, ";");
			this.setVT(vt, ";");
		}
	}
	
	public ArrayList<String> getVN(){
		
		return this.VN;
	}
	
	public ArrayList<String> getVT(){
		
		return this.VT;
	}
	
	public Productions getP(){
		
		return this.P;
	}
	
	public String getS(){
		
		return this.S;
	}
	
	//gli passo tutta la stringa dei non terminal
	public void setVN(String vn, String delimiter){
		
		this.VN= Utility.ArrayToList(Utility.StringSplitByDelimiter(vn, delimiter));
	}
	
	public void setVT(String vt, String delimiter){
		
		this.VT= Utility.ArrayToList(Utility.StringSplitByDelimiter(vt, delimiter));
	}
	
	public void setP(String productions, String delimiter){
		
		String[] prod= Utility.StringSplitByDelimiter(productions, delimiter);
		String tmpKey, tmpProduction;
		int index=0;
		
		for(String tmp : prod){
			
			index= tmp.indexOf("->");
			tmpKey= tmp.substring(0, index);
			tmpProduction= tmp.substring(index+1);
			this.P.addProduction(tmpKey, tmpProduction);
		}
	}
	
	public void setVT(ArrayList<String> vt){
		
		this.VT= vt;
	}
	
	public void setVN(ArrayList<String> vn){
		
		this.VN= vn;
	}
	
	public void setP(Productions p){
		
		this.P= p;
	}
	
	public void setS(String s){
		
		if(s.equals(null)) s= "";
		
		this.S= s;
	}
}
